"""author: wenyao
   data: 2021/3/31
   project: devopscmdb
"""
#形参划分

#必选参数
#默认参数
#可变长位置参数
#可变长关键字参数

#实参划分

#位置参数
#关键字参数

#必选参数
#
# def func01(name, age, sex):
#     print(f"my name is {name}, age is {age}, sex is {sex}")
#
# #参数必须传递
# func01("wenyao",18,"f")

#默认参数
# def func02(name, age, sex="f"):
#     print(f"my name is {name}, age is {age}, sex is {sex}")
#
# func02("wy",18)
# func02("wy2",18,"m")
# func02(age=18,name="wy3")
# #func02(age=18,"wy4")
# func02("wy4",age=18)

#注意定义顺序， 默认参数放在必选参数的后面
#实参使用顺序，  位置参数放在关键字参数的前面

#可变长位置参数
# def myargs(*num):
#     print(*num)
#     print(type(num), num)
#
# myargs(1)
# myargs(1,2)
# myargs(1,2,3)

#packing  and unpacking
#packing
#1,2  == >  元组 (1,2)
#unpacking
#*num  -->(1,2)  ---> 1,2
#       -->[1,2]  ---> 1,2

# lst = ["a","b","c"]
# print("first item is {},second item is {}, third item is {}".format("a","b","c"))
# print("first item is {},second item is {}, third item is {}".format(lst[0],lst[1],lst[2]))
# print("first item is {},second item is {}, third item is {}".format(*lst))

#可变长关键字参数
#packing   -- > a=1,b=2 -->字典 {"a":1,"b":2}
#unpacking  --> {"a":1,"b":2} --> a=1,b=2
# def myargs2(**num):
#     print(num)

# myargs2()
# myargs2(a=1,b=2)
# myargs2(a=1,b=2,c=2)
#
# >>> dict1 = {"a":1,"b":2}
# >>> dict2 = {"c":3,"d":4}
# >>> dict(dict1,dict2)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: dict expected at most 1 arguments, got 2
# >>> dict(dict1,**dict2)
# {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# >>> dict(dict1,c=3,d=4)
# {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# >>> print(**dict2)

#  参数定义的先后
# • 最佳方式：mysun(必选参数, *args, 默认参数, **kargs)
# • 不是每项都需要，如果需要的话，要按上述顺序
#  参数的调用
# • mysum(位置参数，关键字参数）


#可变长位置参数和可变长关键字参数来实现n个数的和相加
# def add(*args):
#     # sum = 0
#     # for i in args:
#     #     sum += i
#     # print(sum)
#
#     result = sum(args)
#     print(result)
#
# add(1,2,3)
#
# def add2(**kwargs):
#     result = sum(kwargs.values())
#     print(result)
# add2(a=5,b=3,c=7)

#函数的return语句
#退出函数，并且返回结果的
#一旦执行到return，就退出，不会执行后面的语句了
#如果函数没有return语句，默认返回None。如果return后面不接任何表达式，也是返回None
#return可以有多个
#return 可以返回多个值

# def maxnum_test(x,y):
#     print("return语句。。。。。。。。")
#     if x>y:
#         print("return x")
#         return x
#     elif x<y:
#         print("reurn y")
#         return y
#     return x,y
#     print("return end.........")
#
# t1 = maxnum_test(2,3)
# print("####################")
# print(t1)
# t2,t3 = maxnum_test(2,2)
# print(t2)
# print(t3)

##########匿名函数
#不需要创建函数名
#只能有一个表达式，不用写return，该表达式的结果就是返回值
#定义规则：
# lambda  args1: 表达式
#
# def add(a,b):
#     return a+b
# print(add(1,2))
#
# add2 = lambda x,y: x+y
# print(add2(3,4))

# #使用匿名函数来返回来个数之间的最大值
# comp = lambda x,y: max(x,y)
# comp2 = lambda x,y: x if x>y else y
# print(comp2(1,3))
#
# #list
# #将浮点数保留两位小数 使用lambda实现
# lst = [1.2222,3.3333,4.44444,5.55555]
# f = lambda x:float(f"{x:.2f}")


####递归函数###################
#自己调用自己，形成循环
#出口条件，即递归“什么时候结束”，
# 这个通常在递归函数的开始就写好可以通过递归调用来缩小问题规模，且新问题与原问题有着相同的形式。


#1、找规律
#2、找出口

# def func01(num):
#     sum = 1
#     for i in range(1,num+1):
#         sum *=i
#     return sum
#
# print(func01(6))

#6! = 6 * 5!
#5! = 5 * 4!
# def func02(n):
#     if n == 1:
#         return 1
#     return n*func02(n-1)
#
# print(func02(6))

#尽量避免使用递归，除非没有更好的算法或者某种特定情况下使用递归
#每次递归都会保存在内存中，非常的占用内存，效率低下
#python中默认的递归深度999

#使用递归函数实现斐波拉契数列
#1,1,2,3,5,8,13
#f(n) = f(n-1)+f(n-2)



#有一对雌雄兔，每两个月就繁殖雌雄兔一对，问n个月之后有多少对兔子
#第一，第二个月： 1对
#第三，第四个月： 2对
#第五，第六个月： 4对
#第七，第八个月： 8对
#f(n) = f(n-2)*2

# def feibonaqi(n):
#     if n == 1 or n == 2:
#         return 1
#     else:
#         return feibonaqi(n-1) + feibonaqi(n-2)
#
# for i in range(1,10):
#     print(feibonaqi(i),end=" ")

# def rabbit(n):
#     if n ==0 or n ==1 or n ==2:
#         return 1
#     if n < 0:
#         return n
#     elif n >= 3:
#         return rabbit(n-2)*2
#
# print(rabbit(10))

#######函数的参数传递##########
#本质上传递的是引用

#不可变数据类型传递
# def func1(x):
#     print(x)
#     x = 100
#     print(x)
#
# x = 1
# func1(x)
# print(x)

#可变数据类型传递
# def f(x):
#     x[0] = 100
#     print(x)
#
# a = [1,2,3]
# f(a)
# print(a)

#参数定义时，尽量避免定义成一个可变对象
# def f(a = []):
#     a.append(1)
#     print(a)
#
# f()
# f()
# f()


#####变量的作用域
# def f():
#     global x  #声明为全局变量
#     x = 5
#
# x = 1
# f()
# print(x)


#变量名的解析
#LEGB
# LEGB作用域查找原则，当引用一个变量时，python按照以下顺序依次进行查找：
# 1. 从本地变量中 -> Local（function）函数内部
# 2. 在任意上层函数的作用域 -> Enclosing function locals 嵌套函数内部
# 3. 在全局作用域 -> Global（module）
# 4. 最后在内置作用域中查找 -> Built-in（python）

# def f():
#     x=2
#     def f2():
#         x=3
#         print(x)
#         print(__name__)
#     f2()
# x = 1
# f()


#############文档注释#############
#文档字符串是包、模块、类或函数里的第一个用引三号引起来的字符串
def f():
    """
    this is test func
    f()

    :return:
    """

    """
    this is test fun2
    docment
    """
    print("hello world")

print(help(f))

########内建函数与工厂函数
#内建函数： python中自带的，直接使用
#工厂函数： 像一个加工厂，把原材料加工成我们想要的材料输出
  #类型转换函数
  #  int  float  list  tuple set  str dict

#  builtins主要是以下4方面
# • 内建异常
# • 内建变量
# • 工厂函数
# • 内建函数

